﻿using System.Collections.Generic;

public class RandomWaveValuesGenerator : WaveValuesGenerator
{     
    public Stack<float> getWaveValues(float minHeight, float maxHeight, float stepY)
    {
        float waveHeightMax = getWaveHeightMax(minHeight, maxHeight);
        WaveDirection waveDirection = getWaveDirectionFromWaveHeightMax(waveHeightMax);
        
        if (waveHeightMax < 0)
            waveHeightMax = turnWaveHeightMaxPositiveFromWaveDirection(waveHeightMax, waveDirection);

        Stack<float> result = createPingPongNumbersFrom(waveHeightMax, waveDirection, stepY);        

        return result;
    }   

    private float getWaveHeightMax(float minHeight, float maxHeight)
    {
        return UnityEngine.Random.Range(minHeight, maxHeight);
    }

    private WaveDirection getWaveDirectionFromWaveHeightMax(float waveHeightMax)
    {
        WaveDirection result = WaveDirection.Up;

        if (waveHeightMax < 0)
            result = WaveDirection.Down;

        return result;
    }

    private float turnWaveHeightMaxPositiveFromWaveDirection(float waveHeightMax, WaveDirection waveDirection)
    {
        waveHeightMax *= (int)waveDirection;

        return waveHeightMax;
    }

    /// <summary>
    /// example with waveHeightMax=1.0, stepY=0.3 and waveDirection=Up: [0.0, 0.3, 0.6, 0.9, 0.6, 0.3, 0.0]
    /// example with waveHeightMax=1.0, stepY=0.3 and waveDirection=Down: [0.0, -0.3, -0.6, -0.9, -0.6, -0.3, 0.0]
    /// </summary>   
    private Stack<float> createPingPongNumbersFrom(float waveHeightMax, WaveDirection waveDirection, float stepY)
    {
        Stack<float> result = new Stack<float>();

        float heightAmount = 0;

        while (heightAmount < waveHeightMax)
        {
            result.Push(heightAmount * (int)waveDirection);
            heightAmount += stepY;
        }

        while (heightAmount >= 0)
        {
            result.Push(heightAmount * (int)waveDirection);
            heightAmount -= stepY;
        }

        return result;
    }
}